﻿// Copyright (c) 2009 Paul Kohler
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
// and associated documentation files (the "Software"), to deal in the Software without restriction, 
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do 
// so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all copies or substantial 
// portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;

namespace FileSystemDatabase
{
	/// <summary>
	/// A Generic style JSON Repository class for use in projects.
	/// </summary>
	/// <remarks>
	/// <code>
	/// public class Repository : BaseJsonRepository
	/// {
	///		public Repository(string dir): base(dir)
	///		{}
	/// 
	///		public void Save&lt;TItem&gt;(TItem item) where TItem : ModelBase
	///		{
	///		 Save(item, item.ID);
	/// 	}
	///
	/// 	public TItem Create&lt;TItem&gt;() where TItem : ModelBase, new()
	/// 	{
	/// 		ModelBase item = new TItem();
	/// 		item.ID = _database.CreateID();
	/// 		return (TItem) item;
	/// 	}
	/// }
	/// 
	/// public class ModelBase : ItemBase&lt;string&gt;
	/// { }
	/// </code>
	/// </remarks>
	public class BaseJsonRepository
	{
		protected readonly JsonDatabase _database;

		/// <summary>
		/// Initializes a new instance of the <see cref="BaseJsonRepository"/> class.
		/// </summary>
		/// <param name="path">The path to the "database" files.</param>
		public BaseJsonRepository(string path)
		{
			_database = new JsonDatabase(path);
			BackupFilename = "FSDB-Backup.zip";
		}

		/// <summary>
		/// Gets or sets the backup filename.
		/// </summary>
		/// <value>The backup filename, the default is "FSDB-Backup.zip".</value>
		public virtual string BackupFilename { get; set; }

		/// <summary>
		/// Gets the object of type <typeparamref name="TItem"/> by <paramref name="id"/>.
		/// </summary>
		/// <typeparam name="TItem">The type of the item.</typeparam>
		/// <param name="id">The id.</param>
		/// <returns>An object instance or null.</returns>
		public virtual TItem Get<TItem>(string id)
		{
			return _database.Read<TItem>(id);
		}

		/// <summary>
		/// Gets all objects of type <typeparamref name="TItem"/>.
		/// </summary>
		/// <typeparam name="TItem">The type of the item.</typeparam>
		/// <returns>A collection of items.</returns>
		public virtual ICollection<TItem> GetAll<TItem>()
		{
			return _database.Read<TItem>();
		}

		/// <summary>
		/// Saves the item by <typeparamref name="TItem"/> and <paramref name="id"/>.
		/// </summary>
		/// <typeparam name="TItem">The type of the item.</typeparam>
		/// <param name="item">The item.</param>
		/// <param name="id">The id.</param>
		public virtual void Save<TItem>(TItem item, string id)
		{
			_database.Write(item, id);
		}

		/// <summary>
		/// Deletes the item of type <typeparamref name="T"/> by <paramref name="id"/>.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="id">The id.</param>
		public virtual void Delete<T>(string id)
		{
			_database.Delete<T>(id);
		}

		/// <summary>
		/// Deletes the item of type "<paramref name="type"/>" by <paramref name="id"/>.
		/// </summary>
		/// <param name="type">The type of object to delete.</param>
		/// <param name="id">The id.</param>
		public virtual void Delete(Type type, string id)
		{
			_database.Delete(type, id);
		}

		/// <summary>
		/// Backups up all the "database" files and stores the ZIP on disk.
		/// </summary>
		/// <returns>The name of the ZIP file.</returns>
		public virtual string Backup()
		{
			return _database.CreateBackup(BackupFilename);
		}
	}
}